<?php defined('SYSPATH') or die('No direct script access.');

/**
 * Assets Module Controller
 *
 * $Id: assets.php 123 2008-09-20 18:32:02Z alex.aperez $
 *
 * @package		Assets Module
 * @author		Alex Sancho
 * @copyright	(c) 2008 Alex Sancho
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in the
 *	  documentation and/or other materials provided with the distribution.
 * 3. Neither the name of copyright holders nor the names of its
 *	  contributors may be used to endorse or promote products derived
 *	  from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.	IN NO EVENT SHALL COPYRIGHT HOLDERS OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

class Assets_Controller extends Controller 
{
	public $use_cache = false;
	public $cache_lifetime = 0;
	
	protected $mime = '';
	protected $data = '';

	/**
	 * __construct
	 *
	 * @return void
	 *
	 */
	public function __construct() 
	{
		parent::__construct();

		if (expires::check(172800) === false) 
			expires::set(172800);

		if (Kohana::config('assets.cache') === true)
			$this->use_cache = true;
		
		Event::add('system.send_headers', array($this, '_set_headers'));
	}

	/**
	 * __call
	 *
	 * @param string $method
	 * @param array $args
	 *
	 * @return mixed
	 *
	 */
	public function __call($method, $args)
	{
		if (Kohana::config('assets.prevent_hotlink') and (isset($_SERVER['HTTP_REFERER']) and strpos($_SERVER['HTTP_REFERER'], url::base(true, true)) === false))
			Event::run('system.404');

		list($file, $this->mime) = explode('.', $args[0], 2);

		switch($method) 
		{
			case 'css':
			case 'js':
				if ($this->use_cache === true)
				{
					$this->cache_lifetime = Kohana::config('assets.cache_lifetime');

					$this->data = Cache::instance()->get('assets-'.$file);
				}

				if (empty($this->data))
				{
					try 
					{
						$this->data = View::factory('assets/'.$method.'/'.$file, null, $this->mime)->render();
					} 
					catch (Kohana_Exception $e) 
					{
						try
						{
							$this->data = View::factory('assets/'.$method.'/'.$file.'.'.$this->mime)->render();
						}
						catch (Kohana_Exception $e) 
						{
							$this->data = '<!-- media file ('.$args[0].') not found -->';
						}
					}

					if (Kohana::config('assets.compress') === true)
					{
						$compressor = 'compress_'.$this->mime;
						$this->data = $this->$compressor($this->data);
					}
			
					if ($this->use_cache === true)
						Cache::instance()->set('assets-'.$file, $this->data, $this->cache_lifetime);
				}
			break;
			default:
				try 
				{
					$this->data = View::factory('assets/'.$method.'/'.$file, null, $this->mime)->render();
				} 
				catch (Kohana_Exception $e) 
				{
					$this->data = '<!-- media file ('.$args[0].') not found -->';
				}
			break;
		}

		echo $this->data;
	}
	
	/**
	 * _set_headers
	 *
	 * @return void
	 *
	 */
	public function _set_headers()
	{
		if ($this->mime != '')
			$mime = Kohana::config('mimes.'.$this->mime) and header("Content-type: ".$mime[0]."; charset=UTF-8");
	}

	/**
	 * compress_js
	 *
	 * @param string
	 * @return string
	 *
	 */
	private function compress_js($data)
	{
		try 
		{
			include Kohana::find_file('vendor', 'Jsmin');
			return JSMin::minify($data);
		} 
		catch(JSMinException $e) 
		{
			return $data;
		}
	}

	/**
	 * compress_css
	 *
	 * @param string
	 * @return string
	 *
	 */	   
	private function compress_css($data)
	{
		$data = preg_replace('~/\*[^*]*\*+([^/][^*]*\*+)*/~', '', $data);
		$data = preg_replace('~\s+~', ' ', $data);
		$data = preg_replace('~ *+([{}+>:;,]) *~', '$1', trim($data));
		$data = str_replace(';}', '}', $data);
		$data = preg_replace('~[^{}]++\{\}~', '', $data);
		return $data;
	}
	
} //End Assets Controller